import { consumeStyles } from "../custom-style-inject";

function rpxToPx(rpx) {
    console.log("rpxToPx:", rpx);
    return rpx / 100 * window.screen.width;
}

function parseToPx(value) {
    if (!value) {
        return 0;
    }
    if (value.endsWith("rpx")) {
        const num = value.replace(/rpx/g, '')
        return rpxToPx(parseFloat(num));
    } else if (value.endsWith("vh") || value.endsWith("vw")) {
        const num = value.endsWith("vh") ? value.replace(/vh/g, '') : value.replace(/vw/g, '')
        const v = parseFloat(num) * (value.endsWith("vh") ? window.screen.height : window.screen.width) / 100;
        return v;
    } else {
        const num = value.replace(/px/g, '')
        return parseFloat(num);
    }
}

// 布局方向（兼容LTR/RTL）
const TaitankDirection = Object.freeze({
    Inherit: 0,
    LTR: 1,
    RTL: 2
});

// 主轴方向
const FlexDirection = Object.freeze({
    Row: 0,
    RowReverse: 1,
    Column: 2,
    ColumnReverse: 3
});

// 换行模式
const FlexWrapMode = Object.freeze({
    NoWrap: 0,
    Wrap: 1,
    WrapReverse: 2
});

// 对齐方式（包含所有Flexbox对齐选项）
const FlexAlign = Object.freeze({
    Auto: 0,
    Start: 1,
    Center: 2,
    End: 3,
    Stretch: 4,
    Baseline: 5,
    SpaceBetween: 6,
    SpaceAround: 7,
    SpaceEvenly: 8
});

// CSS方向（支持逻辑方向）
const CSSDirection = Object.freeze({
    Left: 0,
    Top: 1,
    Right: 2,
    Bottom: 3,
    Start: 4,
    End: 5,
    Horizontal: 6,
    Vertical: 7,
    All: 8,
    None: -1
});

// 尺寸维度
const Dimension = Object.freeze({
    Width: 0,
    Height: 1
});

// 定位类型
const PositionType = Object.freeze({
    Relative: 0,
    Absolute: 1
});

// 显示模式
const DisplayType = Object.freeze({
    Flex: 0,
    None: 1
});

// 溢出处理
const OverflowType = Object.freeze({
    Visible: 0,
    Hidden: 1,
    Scroll: 2
});

// 节点类型
const NodeType = Object.freeze({
    Default: 0,
    Text: 1
});

// 枚举映射配置器（核心逻辑）
const CSS_ENUM_MAPPER = {
    // 布局方向
    direction: {
        target: TaitankDirection,
        mapping: {
            'inherit': 'Inherit',
            'ltr': 'LTR',
            'rtl': 'RTL'
        }
    },

    // 弹性布局方向
    flexDirection: {
        target: FlexDirection,
        mapping: {
            'row': 'Row',
            'row-reverse': 'RowReverse',
            'column': 'Column',
            'column-reverse': 'ColumnReverse'
        }
    },

    // 对齐方式
    alignItems: {
        target: FlexAlign,
        mapping: {
            'auto': 'Auto',
            'flex-start': 'Start',
            'center': 'Center',
            'flex-end': 'End',
            'stretch': 'Stretch',
            'baseline': 'Baseline',
            'space-between': 'SpaceBetween',
            'space-around': 'SpaceAround',
            'space-evenly': 'SpaceEvenly'
        }
    },

    justifyContent: {
        target: FlexAlign,
        mapping: {
            'auto': 'Auto',
            'flex-start': 'Start',
            'center': 'Center',
            'flex-end': 'End',
            'stretch': 'Stretch',
            'baseline': 'Baseline',
            'space-between': 'SpaceBetween',
            'space-around': 'SpaceAround',
            'space-evenly': 'SpaceEvenly'
        }
    },

    // 溢出处理
    overflow: {
        target: OverflowType,
        mapping: {
            'visible': 'Visible',
            'hidden': 'Hidden',
            'scroll': 'Scroll'
        }
    }
    // 其他属性可继续扩展...
};

function cssValueMatch(cssProperty) {
    const config = CSS_ENUM_MAPPER[cssProperty];
    if (!config) {
        switch (cssProperty) {
            case "flex":
            case "flexGrow":
            case "margin":
            case "maxHeight":
            case "minHeight":
            case "maxWidth":
            case "minWidth":
            case "borderRadius":
                return true;
            default:
                console.warn(`未配置的属性映射: ${cssProperty}`);
                return false;
        }
    }
    return true;
}

/**
 * CSS属性值转枚举值
 * @param {string} cssProperty - CSS属性名（如flexDirection）
 * @param {string} cssValue - CSS属性值（如"row-reverse"）
 * @returns {number|null} 枚举值或null（未找到时）
 */
function cssValueToEnum(cssProperty, cssValue) {
    const config = CSS_ENUM_MAPPER[cssProperty];
    if (!config) {
        return handleSpecialCases(cssProperty, cssValue);
    }
    // 标准化输入值（兼容大小写和连字符）
    const normalizedValue = cssValue.toLowerCase().replace(/-/g, '');

    // 双向匹配策略
    const mappingEntry = Object.entries(config.mapping).find(([cssVal]) => {
        const normalizedCssVal = cssVal.replace(/-/g, '').toLowerCase();
        return normalizedCssVal === normalizedValue;
    });

    console.log("mappingEntry", mappingEntry, config.target[mappingEntry[1]], cssProperty, cssValue);

    return mappingEntry ?
        config.target[mappingEntry[1]] || null :
        handleSpecialCases(cssProperty, cssValue);
}

// 特殊处理逻辑
function handleSpecialCases(property, value) {
    console.log("handleSpecialCases", property, value);
    // 处理数值型枚举（如z-index: 999）
    if (/^\d+$/.test(value)) {
        return Number(value);
    }

    // 处理复合值（如flex: 1 1 auto）
    if (property === 'flex') {
        const [grow, shrink, basis] = value.split(/\s+/);
        return {
            grow: Number(grow),
            shrink: Number(shrink),
            basis: basis === 'auto' ? 'auto' : Number(basis)
        };
    } else if (property === 'flex-grow') {
        return Number(value)
    } else if (property === 'margin') {
        const values = value.split(/\s+/);
        let margin = {
            left: 0,
            top: 0,
            right: 0,
            bottom: 0
        };
        if (values.length == 1) {
            const numPx = parseToPx(values[0]);
            margin.left = margin.right = margin.top = margin.bottom = numPx;
        } else if (values.length == 2) {
            const numLeftRightPx = parseToPx(values[0]);
            const numTopBottomPx = parseToPx(values[1]);
            margin.left = margin.right = numLeftRightPx;
            margin.top = margin.bottom = numTopBottomPx;
        } else if (values.length == 4) {
            [margin.left, margin.top, margin.right, margin.bottom] = [parseToPx(values[0]), parseToPx(values[1]), parseToPx(values[2]), parseToPx(values[3])];
        }
        console.log("parsed margin:", margin);
        return margin;
    } else if (property === 'borderRadius') {
        const values = value.split(/\s+/);
        let borderRadius = {
            topLeft: 0,
            topRight: 0,
            bottomLeft: 0,
            bottomRight: 0
        };
        if (values.length == 1) {
            const numPx = parseToPx(values[0]);
            borderRadius.topLeft = borderRadius.topRight = borderRadius.bottomLeft = borderRadius.bottomRight = numPx;
        } else if (values.length == 2) {
            const numLeftRightPx = parseToPx(values[0]);
            const numTopBottomPx = parseToPx(values[1]);
            borderRadius.topLeft = borderRadius.topRight = numLeftRightPx;
            borderRadius.bottomLeft = borderRadius.bottomRight = numTopBottomPx;
        } else if (values.length == 4) {
            [borderRadius.topLeft, borderRadius.topRight, borderRadius.bottomRight, borderRadius.bottomLeft] = [parseToPx(values[0]), parseToPx(values[1]), parseToPx(values[2]), parseToPx(values[3])];
        }
        console.log("parsed borderRadius:", borderRadius);
        return borderRadius;
    } else {
        console.log("特殊但是又不是很特殊的属性: ", property, value);
        return parseToPx(value);
    }

    return null;
}


var objectId = 1;
const idGenerator = () => objectId++;

class Base {
    constructor(className, ...params) {
        this.className = className;
        this.objID = idGenerator();
        this.recycler = new Recycler(this.objID);
        invoke(this.className, this.objID, "constructor", this, ...params);
    }
}

class ViewBase extends Base {
    constructor(className, ...params) {
        super(className, ...params);
        this.width = 0;
        this.height = 0;
        this.left = 0;
        this.top = 0;
        this.layoutProps = {};
        this.parent = null;
        this.indexInParent = 0;
    }

    onSizeChanged(left, top, width, height) {
        invoke(this.className, this.objID, "onSizeChanged", left, top, width, height);
    }

    setBorderRadius(borderRadius) {
        invoke(this.className, this.objID, "setBorderRadius", borderRadius.topLeft, borderRadius.topRight, borderRadius.bottomRight, borderRadius.bottomLeft);
    }

    set backgroundColor(color) {
        console.log("called set backgroundColor", color)
        invoke(this.className, this.objID, "setBackgroundColor", color);
    }

    set background(value) {
        console.log("called set background")
        invoke(this.className, this.objID, "setBackground", value);
    }
}

class View extends ViewBase {
    constructor(name) {
        super("View", name);
        this.name = name;
        this.index = 0;
        this.childrenViews = new Map();
        this.childrenNodes = new Map();
    }

    collectNodes() {
        let root = new TaitanLayoutNode(0);
        const sortedChildrenViewsArray = Array.from(this.childrenViews).sort((a, b) => a[1].indexInParent - b[1].indexInParent);
        sortedChildrenViewsArray.forEach((arr) => {
            let child = arr[1];
            let objectId = arr[0];
            const key = child.indexInParent;
            let childNode = new TaitanLayoutNode(key);
            Object.assign(childNode, child.layoutProps);
            if (child.layoutProps.margin) {
                childNode.setMargin(CSSDirection.Left, child.layoutProps.margin.left);
                childNode.setMargin(CSSDirection.Top, child.layoutProps.margin.top);
                childNode.setMargin(CSSDirection.Right, child.layoutProps.margin.right);
                childNode.setMargin(CSSDirection.Bottom, child.layoutProps.margin.bottom);
            }
            console.log("create taitan layout node childNode: ", childNode, child.layoutProps);
            root.insertChild(childNode, key);
            this.childrenNodes.set(key, childNode);
        });
        Object.assign(root, this.layoutProps);
        if (this.layoutProps.margin) {
            root.setMargin(CSSDirection.Left, this.layoutProps.margin.left);
            root.setMargin(CSSDirection.Top, this.layoutProps.margin.top);
            root.setMargin(CSSDirection.Right, this.layoutProps.margin.right);
            root.setMargin(CSSDirection.Bottom, this.layoutProps.margin.bottom);
        }
        return root;
    }

    layout() {
        let root = this.collectNodes();
        root.width = this.width;
        root.height = this.height;

        // 计算视图尺寸信息
        root.doLayout();
        console.log("parent dolayout");

        // 根据计算的视图尺寸信息，对子View的宽高进行布局
        for (let [key, value] of this.childrenNodes.entries()) {
            // let childView = this.childrenViews.get(key);
            const objects = [...this.childrenViews.values()].filter(obj => obj.indexInParent === key);
            if (objects.length <= 0) {
                continue;
            }
            let childView = objects[0];
            if (childView instanceof Comment) {
                childView.width = 0
                childView.height = 0;
                childView.left = 0;
                childView.top = 0;
                continue;
            }
            childView.width = value.width;
            childView.height = value.height;
            childView.left = value.left;
            childView.top = value.top;
            if (childView.layoutProps.borderRadius) {
                childView.setBorderRadius(childView.layoutProps.borderRadius);
            }
            childView.onSizeChanged(childView.left, childView.top, childView.width, childView.height);
            if (childView instanceof View) {
                console.log("child is view, call there dolayout");
                // 父View得到自己的尺寸之后，通知子View进行布局
                childView.layout();
            }
            // console.log('c' + key + '.w', value.width, 'c.h', value.height, 'c.left', value.left, 'c.top', value.top);
        }
        // console.log('p.w', this.name, this.width, 'c.h', this.height);
        // 通知对View进行布局（此时，View的尺寸都是已知的了）
        invoke(this.className, this.objID, "requestLayout");
        this.childrenNodes.clear();

        if ("background" in this.layoutProps) {
            this.background = this.layoutProps["background"];
        }
        if ("backgroundColor" in this.layoutProps) {
            this.backgroundColor = this.layoutProps["backgroundColor"];
        }
    }

    appendChild(child) {
        child.parent = this;
        this.childrenViews.set(child.objID, child);
        console.log("appendChild, view.index=", this.index, child.objID);
        this.index += 1;
        invoke(this.className, this.objID, "appendChild", child.objID);
    }

    // 废弃，没啥用了
    insertBefore(child, anchor) {
        child.parent = this;
        this.childrenViews.set(child.objID, child);
        this.index += 1;
        invoke(this.className, this.objID, "insertBefore", child.objID, anchor.objID);
    }

    removeChild(child) {
        console.log("removeChild, view.objID=", child.objID);
        child.parent = null;
        this.childrenViews.delete(child.objID);
        invoke(this.className, this.objID, "removeChild", child.objID);
    }

    requestLayout() {
        if (this.parent != null) {
            console.log("requestLayout");
            this.parent.layout();
        }
    }
}

class Text extends ViewBase {
    constructor() {
        super("Text");
    }

    setText(text) {
        this.text = text
        invoke(this.className, this.objID, "setText", text)
    }

    notify() {
        // invoke(this.className, this.objID, "notify", this, function (result) {
        //     console.log(result);
        // })
    }

    set color(c) {
        invoke(this.className, this.objID, "setColor", c);
    }

    set fontSize(size) {
        invoke(this.className, this.objID, "setFontSize", size);
    }

    // set onClick(callback) {
    //     console.log("set onClick callback");
    //     invoke(this.className, this.objID, "setOnClick", callback);
    // }

    setOnClickListener(callback) {
        this.onClick = callback;
        invoke(this.className, this.objID, "setOnClick", callback);
    }
}

class Image extends ViewBase {
    constructor() {
        super("Image");
    }

    set src(c) {
        invoke(this.className, this.objID, "setSrc", c)
    }

    load(url, callback) {
        invoke(this.className, this.objID, "load", url, callback)
    }
}

class Comment extends Text {
    constructor() {
        super("Text");
    }
}




export {
    View as View,
    Image as Image,
    Text as Text,
    Comment as Comment,
    rpxToPx as rpxToPx,
    cssValueToEnum as cssValueToEnum,
    cssValueMatch as cssValueMatch,
    TaitankDirection as TaitankDirection,
    FlexDirection as FlexDirection,
    FlexWrapMode as FlexWrapMode,
    FlexAlign as FlexAlign,
    CSSDirection as CSSDirection,
    Dimension as Dimension,
    PositionType as PositionType,
    DisplayType as DisplayType,
    OverflowType as OverflowType,
    NodeType as NodeType
};